package com.xiaodimall.beforesys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaodimall.beforesys.mapper.GoodsMapper;
import com.xiaodimall.beforesys.mapper.OrderItemMapper;
import com.xiaodimall.beforesys.mapper.OrderMapper;
import com.xiaodimall.beforesys.mapper.ShoppingCartItemMapper;
import com.xiaodimall.beforesys.pojo.*;
import com.xiaodimall.beforesys.service.CartService;
import com.xiaodimall.beforesys.service.OrderService;
import com.xiaodimall.beforesys.vo.OrderDetailVO;
import com.xiaodimall.beforesys.vo.OrderItemVO;
import com.xiaodimall.beforesys.vo.OrderListVO;
import com.xiaodimall.common.Constants;
import com.xiaodimall.common.MallOrderStatusEnum;
import com.xiaodimall.common.PayTypeEnum;
import com.xiaodimall.common.ServiceResultEnum;
import com.xiaodimall.exception.MallException;
import com.xiaodimall.utils.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @author wyc
 * @description
 * @ClassName AdminOrderServiceImpl
 * @date 2022/11/29 14:10
 */
@Service
@Transactional
public class OrderServiceImpl implements OrderService {


    //注入购物车商品业务层模块
    @Resource
    CartServiceImpl cartServiceImpl;
    //注入订单持久层接口
    @Resource
    OrderMapper orderMapper;
    //注入订单详情持久层接口
    @Resource
    OrderItemMapper orderItemMapper;
    //注入商品持久层接口
    @Resource
    GoodsMapper goodsMapper;
    //注入购物车详情持久层接口
    @Resource
    ShoppingCartItemMapper shoppingCartItemMapper;



    /**
     * 根据购物车商品保存订单信息
     * @author WYC
     * @param httpSession
     * @return: 返回结果集
     * @date: 2022/12/1 9:23
     */
    @Override
    public String saveOrder(HttpSession httpSession) {
        User user = (User) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        //判断登录是否超时
        if (user == null) {
            return ServiceResultEnum.SESSION_ERROR_NULL.getResult();
        }
        Map<String, Object> map = cartServiceImpl.showCartMsg(httpSession);
        List<Goods> myShoppingCartItems = (List<Goods>) map.get("list");
        if (StringUtils.isEmpty(user.getAddress().trim())) {
            //无收货地址
            MallException.fail(ServiceResultEnum.NULL_ADDRESS_ERROR.getResult());
        }
        if (CollectionUtils.isEmpty(myShoppingCartItems)) {
            //购物车中无数据则跳转至错误页
            MallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        }

        //保存订单并返回订单号
        ArrayList<Long> cartIdList = new ArrayList<>();
        ArrayList<Long> goodsIds = new ArrayList<>();
        for (Goods myShoppingCartItem : myShoppingCartItems) {
            cartIdList.add(myShoppingCartItem.getCartItemId());
            goodsIds.add(myShoppingCartItem.getGoodsId());
        }
        List<Goods> MallGoods = goodsMapper.selectByPrimaryKeys(goodsIds);
        //检查是否包含已下架商品
        List<Goods> goodsNotSelling = new ArrayList<>();
        for (Goods mallGood : MallGoods) {
            if (mallGood.getGoodsSellStatus()!=0) {
                goodsNotSelling.add(mallGood);
            }
        }
        if (!CollectionUtils.isEmpty(goodsNotSelling)) {
            //goodsListNotSelling 对象非空则表示有下架商品
            MallException.fail(goodsNotSelling.get(0).getGoodsName() + "已下架，无法生成订单");
        }
        //把goodsId封装到map集合
        Map<Long, Goods> MallGoodsMap = MallGoods.stream().collect(Collectors.toMap(Goods::getGoodsId, Function.identity(), (entity1, entity2) -> entity1));
        //判断商品库存
        for (Goods good : myShoppingCartItems) {
            //查出的商品中不存在购物车中的这条关联商品数据，直接返回错误提醒
            if (!MallGoodsMap.containsKey(good.getGoodsId())) {
                MallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
            }
            //根据商品的id获取商品库存的数量
            Integer stockNum = MallGoodsMap.get(good.getGoodsId()).getStockNum();
            //判断购买数量和商品库存数量
            //存在数量大于库存的情况，直接返回错误提醒
            if (good.getGoodsCount() > stockNum) {
                MallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
            }
        }
        //删除购物项
        if (!CollectionUtils.isEmpty(cartIdList) && !CollectionUtils.isEmpty(goodsIds) && !CollectionUtils.isEmpty(MallGoods)) {
            //执行批量删除
            int row = shoppingCartItemMapper.deleteBatch(cartIdList);
            if (row > 0) {
                int updateStockNumResult = goodsMapper.updateStockNum(myShoppingCartItems);
                if (updateStockNumResult < 1) {
                    MallException.fail(ServiceResultEnum.SHOPPING_ITEM_COUNT_ERROR.getResult());
                }
                //生成订单号
                String orderNo = NumberUtil.genOrderNo();

                //保存订单
                Order MallOrder = new Order();
                MallOrder.setOrderNo(orderNo);
                MallOrder.setUserId(user.getUserId());
                MallOrder.setUserAddress(user.getAddress());
                int priceTotal = (int) map.get("price");
                if (priceTotal < 1) {
                    MallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                MallOrder.setTotalPrice(priceTotal);
                //订单详情
                String extraInfo = "";
                MallOrder.setExtraInfo(extraInfo);
                //生成订单项并保存订单项纪录
                int r = orderMapper.insert(MallOrder);
                if (r > 0) {
                    //生成所有的订单项快照，并保存至数据库
                    List<OrderItem> MallOrderItems = new ArrayList<>();
                    for (Goods MallShoppingCartItemVO : myShoppingCartItems) {
                        OrderItem MallOrderItem = new OrderItem();
                        //使用BeanUtil工具类将MallShoppingCartItemVO中的属性复制到MallOrderItem对象中
                        BeanUtil.copyProperties(MallShoppingCartItemVO, MallOrderItem);
                        MallOrderItem.setOrderId(MallOrder.getOrderId());
                        MallOrderItems.add(MallOrderItem);
                    }
                    //批量保存至数据库
                    int i = orderItemMapper.insertBatch(MallOrderItems);
                    if (i > 0) {
                        //所有操作成功后，将订单号返回，以供Controller方法跳转到订单详情
                        //跳转到订单详情页
                        return orderNo;
                    }
                    MallException.fail(ServiceResultEnum.ORDER_PRICE_ERROR.getResult());
                }
                MallException.fail(ServiceResultEnum.DB_ERROR.getResult());
            }
            MallException.fail(ServiceResultEnum.DB_ERROR.getResult());
        }
        MallException.fail(ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult());
        return ServiceResultEnum.SHOPPING_ITEM_ERROR.getResult();
    }

    /**
     * 根据订单编号查看订单详情
     * @author WYC
     * @param request
     * @param orderNo
     * @param httpSession
     * @return: 返回订单详情页面
     * @date: 2022/12/1 9:21
     */
    @Override
    public String getOrderDetailByOrderNo(HttpServletRequest request, String orderNo, HttpSession httpSession) {
        User user = (User) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        //判断登录是否超时
        if (user == null) {
            return ServiceResultEnum.SESSION_ERROR_NULL.getResult();
        }
        //获取订单信息
        Order myOrderItem = orderMapper.selectByOrderNo(orderNo);
        if (myOrderItem != null) {
            //验证是否是当前userId下的订单，否则报错
            if (myOrderItem.getUserId()!=user.getUserId()) {
                return "error/error_5xx";
            }
            //获取订单里的所有商品信息
            List<OrderItem> orderItems = orderItemMapper.selectList(
                    new QueryWrapper<OrderItem>()
                            .eq("order_id",myOrderItem.getOrderId()));

            //获取订单项数据
            if (!CollectionUtils.isEmpty(orderItems)) {
                //封装并转换
                List<OrderItemVO> newOrderItemVOS = BeanUtil.copyList(orderItems, OrderItemVO.class);
                for (OrderItemVO newOrderItemVO : newOrderItemVOS) {
                    System.out.println(newOrderItemVO);
                }
                OrderDetailVO newOrderDetailVO = new OrderDetailVO();
                BeanUtil.copyProperties(myOrderItem, newOrderDetailVO);
                //获取订单状态类型
                Integer orderStatus = newOrderDetailVO.getOrderStatus();
                //获取订单状态信息
                String orderStatusName = MallOrderStatusEnum.getMallOrderStatusEnumByStatus(orderStatus).getName();
                //设置订单状态信息
                newOrderDetailVO.setOrderStatusString(orderStatusName);
                //支付状态类型
                Integer payType = newOrderDetailVO.getPayType();
                //支付状态信息
                String payTypeName = PayTypeEnum.getPayTypeEnumByType(payType).getName();
                //设置支付状态
                newOrderDetailVO.setPayTypeString(payTypeName);
                newOrderDetailVO.setOrderItemVOS(newOrderItemVOS);
                if (newOrderDetailVO == null) {
                    return "error/error_5xx";
                }
                request.setAttribute("orderDetailVO", newOrderDetailVO);
                return "mall/order-detail";
            }
        }
        return null;
    }



    /**
     * 根据用户id获取用户的所有订单信息
     * @author WYC
     * @param params
     * @param request
     * @param httpSession
     * @return: 返回到我的订单页面
     * @date: 2022/12/1 9:20
     */
    @Override
    public String getMyOrders(@RequestParam Map<String, Object> params,
                              HttpServletRequest request,
                              HttpSession httpSession) {
        User user = (User) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        //判断登录是否超时
        if (user == null) {
            return ServiceResultEnum.SESSION_ERROR_NULL.getResult();
        }
        //添加信息到map集合
        params.put("userId", user.getUserId());
        if (StringUtils.isEmpty(params.get("page"))) {
            params.put("page", 1);
        }
        //设置订单分页显示数量
        params.put("limit", Constants.ORDER_SEARCH_PAGE_LIMIT);
        PageQueryUtil pageUtil = new PageQueryUtil(params);
        //封装我的订单数据
        int total = orderMapper.getTotalOrders(pageUtil);
        List<Order> newOrders = orderMapper.findOrderList(pageUtil);
        List<OrderListVO> orderListVOS = new ArrayList<>();
        //如果订单总数大于0就封装数据
        if (total > 0) {
            //数据转换 将实体类转成vo
            orderListVOS = BeanUtil.copyList(newOrders, OrderListVO.class);
            //设置订单状态中文显示值
            for (OrderListVO newOrderListVO : orderListVOS) {
               //获取订单状态类型
                MallOrderStatusEnum orderStatus= MallOrderStatusEnum.getMallOrderStatusEnumByStatus(newOrderListVO.getOrderStatus());
                //获取订单状态中文
                String orderStatusName = orderStatus.getName();
                //设置订单的状态
                newOrderListVO.setOrderStatusString(orderStatusName);
            }

            //获取所有订单id封装到集合
            List<Long> orderIds = new ArrayList<>();
            for (Order order : newOrders) {
                Long orderId = order.getOrderId();
                orderIds.add(orderId);
            }
            if (!CollectionUtils.isEmpty(orderIds)) {
                //调用查询出所有订单的详情
                List<OrderItem> orderItems = orderItemMapper.selectByOrderIds(orderIds);

                //封装订单信息到map集合,显示到我的订单页面
                Map<Long, List<OrderItem>> itemByOrderIdMap = new HashMap<>();
                for (OrderItem orderItem : orderItems) {
                    Long orderId = orderItem.getOrderId();
                    if (orderId==orderItem.getOrderId()) {

                        List<OrderItem> items = orderItemMapper.selectList(
                                new QueryWrapper<OrderItem>().
                                        eq("order_id", orderId));
                        itemByOrderIdMap.put(orderId,items );
                    }
                }
                for (OrderListVO newOrderListVO : orderListVOS) {
                    //封装每个订单列表对象的订单项数据
                    //判断每个信息是否一致
                    if (itemByOrderIdMap.containsKey(newOrderListVO.getOrderId())) {
                        //获取每个订单的数据
                        List<OrderItem> orderItemListTemp = itemByOrderIdMap.get(newOrderListVO.getOrderId());
                        //将NewOrderItem对象列表转换成NewOrderItemVO对象列表
                        List<OrderItemVO> newOrderItemVOS = BeanUtil.copyList(orderItemListTemp, OrderItemVO.class);
                        newOrderListVO.setOrderItemVOS(newOrderItemVOS);
                    }
                }
            }
        }
        PageResult pageResult = new PageResult(orderListVOS, total, pageUtil.getLimit(), pageUtil.getPage());
        //绑定数据
        request.setAttribute("orderPageResult", pageResult);
        request.setAttribute("path", "orders");
        return "mall/my-orders";
    }



    /**
     * 根据订单的编号关闭订单
     * @author WYC
     * @param orderNo
     * @param httpSession
     * @return: 结果集
     * @date: 2022/12/1 9:19
     */
    @Override
    public String cancelOrder(String orderNo, HttpSession httpSession) {
        User user = (User) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        //判断登录是否超时
        if (user == null) {
            return ServiceResultEnum.SESSION_ERROR_NULL.getResult();
        }
        //获取订单信息
        Order newOrder = orderMapper.selectByOrderNo(orderNo);
        if (newOrder != null) {
            //验证是否是当前userId下的订单，否则报错
            if (newOrder.getUserId()== user.getUserId()){
                //调用执行修改订单状态的语句
                int row = orderMapper.update(
                        new Order().setOrderStatus(MallOrderStatusEnum.ORDER_CLOSED_BY_MALLUSER.getOrderStatus()),
                        new QueryWrapper<Order>().eq("order_no", orderNo));
                if (row>0) {
                    return ServiceResultEnum.SUCCESS.getResult();
                } else {
                    return ServiceResultEnum.DB_ERROR.getResult();
                }

            }
            return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();

    }



    /**
     * 确认收货
     * @author WYC
     * @param orderNo
     * @param httpSession
     * @return: 结果集
     * @date: 2022/12/1 11:08
     */
    @Override
    public String finishOrder(String orderNo, HttpSession httpSession) {
        User user = (User) httpSession.getAttribute(Constants.MALL_USER_SESSION_KEY);
        //判断登录是否超时
        if (user == null) {
            return ServiceResultEnum.SESSION_ERROR_NULL.getResult();
        }
        //获取订单信息
        Order newOrder = orderMapper.selectByOrderNo(orderNo);
        if (newOrder != null) {
            //验证是否是当前userId下的订单，否则报错
            if (newOrder.getUserId()!= user.getUserId()){
                return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
            }
            //订单状态判断
            if (MallOrderStatusEnum.OREDER_EXPRESS.equals(newOrder.getOrderStatus())){
                return ServiceResultEnum.ORDER_STATUS_ERROR.getResult();
            }
            newOrder.setOrderStatus(MallOrderStatusEnum.ORDER_SUCCESS.getOrderStatus());
            newOrder.setUpdateTime(new Date());
            //修改订单状态
            int row = orderMapper.updateById(newOrder);
            if (row > 0) {
                return ServiceResultEnum.SUCCESS.getResult();
            } else {
                return ServiceResultEnum.DB_ERROR.getResult();
            }
        }
        return ServiceResultEnum.ORDER_NOT_EXIST_ERROR.getResult();
    }

}
